import time
import random
import os
import json
from android_model import select_features
import android_model
import pe_model
import elf_model
from loguru import logger

# from loguru import logger
ANDR_STORE_PATH = "./static/files"
PE_STORE_PATH = "./static/files"
ELF_STORE_PATH = "./static/files"


def android(file, key):
    # time.sleep(10)
    start_time = time.time()
    try:
        flag, features_string, features_vec = android_model.process(
            file, select_features)
        path = os.path.join(ANDR_STORE_PATH, key + ".json")
        data = {}
        data["type"] = "apk"
        data['intents'] = features_string[0]
        data["permissions"] = features_string[1]
        data["apis"] = features_string[2]
        data["vectors"] = features_vec
        if flag == 0:
            store(path, data)
            return "benign"
        elif flag == 1:
            store(path, data)
            return "malignance"
    except Exception as ex:
        logger.error(ex)
        return "error"
    finally:
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"File_{key} android full execution time: {execution_time} s")

    # return random.choice(["malignance","benign"])


def android_json(file, key):
    start_time = time.time()
    try:
        data = json.loads(file)
        features = [data["intents"], data["permissions"], data["apis"]]
        flag, _, _ = android_model.process_string(
            features, select_features)
        path = os.path.join(ANDR_STORE_PATH, key + ".json")
        if flag == 0:
            store(path, data)
            return "benign"
        elif flag == 1:
            store(path, data)
            return "malignance"
    except Exception as ex:
        logger.error(ex)
        return "error"
    finally:
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"File_{key} android features execution time: {execution_time} s")


def analyse_features_android(file, key):
    start_time = time.time()
    try:
        features_string = android_model.analyse(file, raw=True)
        data = {}
        data["type"] = "apk"
        data['intents'] = features_string[0]
        data["permissions"] = features_string[1]
        data["apis"] = features_string[2]
        path = os.path.join(ANDR_STORE_PATH, key + ".json")
        store(path, data)
        return True
    except Exception as ex:
        logger.error(ex)
        return False
    finally:
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"File_{key} android analyse execution time: {execution_time} s")


def android_convert(file, key):
    start_time = time.time()
    data = json.loads(file)
    features_string = [data["intents"], data["permissions"], data["apis"]]
    try:
        features_vec = android_model.extract_features(features_string,
                                                      select_features)
        data["vectors"] = features_vec
        path = os.path.join(ANDR_STORE_PATH, key + ".json")
        store(path, data)
        return True
    except Exception as ex:
        logger.error(ex)
        return False
    finally:
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"File_{key} android extract execution time: {execution_time} s")


def android_predict(file):
    start_time = time.time()
    try:
        data = json.loads(file)
        pred = android_model.model_predict(data['vectors'])
        if pred == 0:
            return "benign"
        else:
            return "malignance"
    except Exception as ex:
        logger.error(ex)
        return None
    finally:
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"File android predict execution time: {execution_time} s")


def store(path, data):
    with open(path, "w+") as f_out:
        json.dump(data, f_out)


def pe(file, key):
    start_time = time.time()
    try:
        flag, features = pe_model.process(file)
        data = {}
        data["type"] = "pe"
        data["static"] = features[0]
        data["api"] = features[1]
        data["dll"] = features[2]
        path = os.path.join(PE_STORE_PATH, key + ".json")
        if flag == 0:
            store(path, data)
            return "benign"
        elif flag == 1:
            store(path, data)
            return "malignance"
    except Exception as ex:
        logger.error(ex)
        return "error"
    finally:
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"File_{key} pe full execution time: {execution_time} s")


def pe_json(file, key):
    start_time = time.time()
    try:
        data = json.loads(file)
        features = [data["static"], data["api"], data["dll"]]
        flag, features = pe_model.process_string(features)
        path = os.path.join(PE_STORE_PATH, key+".json")
        if flag == 0:
            store(path, data)
            return "benign"
        elif flag == 1:
            store(path, data)
            return "malignance"
    except Exception as ex:
        logger.error(ex)
        return "error"
    finally:
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"File_{key} pe features execution time: {execution_time} s")

    return 0


def analyse_features_pe(file, key):
    start_time = time.time()
    try:
        features = pe_model.extract_features(file)
        data = {}
        data["type"] = "pe"
        data["static"] = features[0]
        data["api"] = features[1]
        data["dll"] = features[2]
        path = os.path.join(PE_STORE_PATH, key + ".json")
        store(path, data)
        return True
    except Exception as ex:
        logger.error(ex)
        return False
    finally:
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"File_{key} pe analyse execution time: {execution_time} s")


def pe_predict(json):
    start_time = time.time()
    try:
        data = json
        static, api, dll = data["static"], data["api"], data["dll"]
        pred = pe_model.model_predict(static)
        if pred == 0:
            return "benign"
        else:
            return "malignance"
    except Exception as ex:
        logger.error(ex)
        return None
    finally:
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"File pe predict execution time: {execution_time} s")


def elf(file, key):
    start_time = time.time()
    try:

        flag, features = elf_model.process(file)
        data = {}
        data["type"] = "elf"
        data["static"] = features
        path = os.path.join(ELF_STORE_PATH, key+".json")
        if flag == 0:
            store(path, data)
            return "benign"
        elif flag == 1:
            store(path, data)
            return "malignance"
    except Exception as ex:
        logger.error(ex)
        return "error"
    finally:
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"File_{key} elf full execution time: {execution_time} s")


def elf_json(file, key):
    start_time = time.time()
    try:
        data = json.loads(file)
        features = data["static"]
        flag, features = elf_model.process_string(features)
        data = {}
        data["type"] = "elf"
        data["static"] = features
        path = os.path.join(ELF_STORE_PATH, key+".json")
        if flag == 0:
            store(path, data)
            return "benign"
        elif flag == 1:
            store(path, data)
            return "malignance"
    except Exception as ex:
        logger.error(ex)
        return "error"
    finally:
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"File_{key} elf features execution time: {execution_time} s")


def analyse_features_elf(file, key):
    start_time = time.time()
    try:
        features = elf_model.get_static(file)
        data = {}
        data["type"] = "elf"
        data["static"] = features
        path = os.path.join(ELF_STORE_PATH, key+".json")
        store(path, data)
        return True
    except Exception as ex:
        logger.error(ex)
        return False
    finally:
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"File_{key} elf analyse execution time: {execution_time} s")


def elf_predict(json):
    start_time = time.time()
    try:
        data = json
        features = data["static"]
        pred = elf_model.model_predict(features)
        if pred == 0:
            return "benign"
        else:
            return "malignance"
    except Exception as ex:
        logger.error(ex)
        return None
    finally:
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"File elf predict execution time: {execution_time} s")
